/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.netbeans.modules.php.project.ui.actions.support;

import java.io.File;
import javax.swing.JPanel;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.netbeans.modules.php.project.runconfigs.RunConfigScript;
import org.netbeans.modules.php.project.runconfigs.validation.RunConfigScriptValidator;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.NotificationLineSupport;
import org.openide.filesystems.FileChooserBuilder;
import org.openide.filesystems.FileUtil;
import org.openide.util.NbBundle;

// inspired from ruby project
final class RunFilePanel extends JPanel {
    private static final long serialVersionUID = 92648723648723L;

    private DialogDescriptor dialogDescriptor;
    private NotificationLineSupport notificationLineSupport;

    private RunFilePanel(RunFileActionProvider.RunFileArgs args) {
        initComponents();

        runArgsField.setText(args.getRunArgs());
        workDirField.setText(args.getWorkDir());
        phpOptionsField.setText(args.getPhpOpts());

        workDirField.getDocument().addDocumentListener(new DocumentListener() {

            @Override
            public void insertUpdate(DocumentEvent e) {
                processChange();
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                processChange();
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                processChange();
            }

            private void processChange() {
                validateWorkDir();
            }
        });
    }

    public static RunFileActionProvider.RunFileArgs open(RunFileActionProvider.RunFileArgs args, File file, boolean debug) {
        final RunFilePanel panel = new RunFilePanel(args);
        panel.dialogDescriptor = new DialogDescriptor(
                panel,
                NbBundle.getMessage(RunFilePanel.class, debug ? "LBL_DebugFile" : "LBL_RunFile", file.getName()),
                true,
                DialogDescriptor.OK_CANCEL_OPTION,
                DialogDescriptor.OK_OPTION,
                null);
        panel.notificationLineSupport = panel.dialogDescriptor.createNotificationLineSupport();
        panel.validateWorkDir();
        if (DialogDisplayer.getDefault().notify(panel.dialogDescriptor) == DialogDescriptor.OK_OPTION) {
            return panel.getArgs();
        }
        return null;
    }

    private RunFileActionProvider.RunFileArgs getArgs() {
        RunConfigScript config = createRunConfig();
        return new RunFileActionProvider.RunFileArgs(config.getArguments(), config.getWorkDir(), config.getOptions(), !displayDialog.isSelected());
    }

    private RunConfigScript createRunConfig() {
        return RunConfigScript.create()
                .setOptions(phpOptionsField.getText())
                .setArguments(runArgsField.getText())
                .setWorkDir(workDirField.getText());
    }

    void validateWorkDir() {
        assert notificationLineSupport != null;

        String error = RunConfigScriptValidator.validateRunFileWithoutProject(createRunConfig());
        if (error != null) {
            notificationLineSupport.setErrorMessage(error);
            dialogDescriptor.setValid(false);
            return;
        }
        notificationLineSupport.clearMessages();
        dialogDescriptor.setValid(true);
    }


    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        runArgsLabel = new javax.swing.JLabel();
        runArgsField = new javax.swing.JTextField();
        workDirLabel = new javax.swing.JLabel();
        workDirField = new javax.swing.JTextField();
        browseButton = new javax.swing.JButton();
        phpOptionsLabel = new javax.swing.JLabel();
        phpOptionsField = new javax.swing.JTextField();
        displayDialog = new javax.swing.JCheckBox();

        runArgsLabel.setLabelFor(runArgsField);
        org.openide.awt.Mnemonics.setLocalizedText(runArgsLabel, org.openide.util.NbBundle.getMessage(RunFilePanel.class, "RunFilePanel.runArgsLabel.text")); // NOI18N

        workDirLabel.setLabelFor(workDirField);
        org.openide.awt.Mnemonics.setLocalizedText(workDirLabel, org.openide.util.NbBundle.getMessage(RunFilePanel.class, "RunFilePanel.workDirLabel.text")); // NOI18N

        workDirField.setEditable(false);

        org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(RunFilePanel.class, "RunFilePanel.browseButton.text")); // NOI18N
        browseButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                browseButtonActionPerformed(evt);
            }
        });

        phpOptionsLabel.setLabelFor(phpOptionsField);
        org.openide.awt.Mnemonics.setLocalizedText(phpOptionsLabel, org.openide.util.NbBundle.getMessage(RunFilePanel.class, "RunFilePanel.phpOptionsLabel.text")); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(displayDialog, org.openide.util.NbBundle.getMessage(RunFilePanel.class, "RunFilePanel.displayDialog.text")); // NOI18N

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(phpOptionsLabel)
                            .addComponent(workDirLabel)
                            .addComponent(runArgsLabel))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(runArgsField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 314, Short.MAX_VALUE)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(workDirField, javax.swing.GroupLayout.DEFAULT_SIZE, 206, Short.MAX_VALUE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(browseButton))
                            .addComponent(phpOptionsField, javax.swing.GroupLayout.DEFAULT_SIZE, 314, Short.MAX_VALUE)))
                    .addComponent(displayDialog))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(runArgsLabel)
                    .addComponent(runArgsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(workDirLabel)
                    .addComponent(workDirField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(browseButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(phpOptionsLabel)
                    .addComponent(phpOptionsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(displayDialog))
        );

        displayDialog.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(RunFilePanel.class, "RunFilePanel.displayDialog.AccessibleContext.accessibleDescription")); // NOI18N
    }// </editor-fold>//GEN-END:initComponents

    private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
        File selectedFile = new FileChooserBuilder(RunFilePanel.class)
                .setTitle(NbBundle.getMessage(RunFilePanel.class, "LBL_SelectWorkingDirectory"))
                .setDirectoriesOnly(true)
                .forceUseOfDefaultWorkingDirectory(true)
                .setDefaultWorkingDirectory(new File(createRunConfig().getWorkDir()))
                .showOpenDialog();
        if (selectedFile != null) {
            File workDir = FileUtil.normalizeFile(selectedFile);
            workDirField.setText(workDir.getAbsolutePath());
        }
    }//GEN-LAST:event_browseButtonActionPerformed


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton browseButton;
    private javax.swing.JCheckBox displayDialog;
    private javax.swing.JTextField phpOptionsField;
    private javax.swing.JLabel phpOptionsLabel;
    private javax.swing.JTextField runArgsField;
    private javax.swing.JLabel runArgsLabel;
    private javax.swing.JTextField workDirField;
    private javax.swing.JLabel workDirLabel;
    // End of variables declaration//GEN-END:variables

}
